package com.lagou.cachehomework.controller;


import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.lagou.cachehomework.entity.Recruit;
import com.lagou.cachehomework.repository.RecruitDao;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;



@RestController
@RequestMapping("/cache")
public class CacheController {


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RecruitDao recruitDao;



    LoadingCache<String, Object> cache = CacheBuilder.newBuilder()
            // 设置缓存个数上限，5个
            .maximumSize(5)
            // 缓存刷新时间
            .expireAfterAccess(20,TimeUnit.SECONDS)
            .build(new CacheLoader<String, Object>() {

                //读取数据源
                @Override
                public Object load(String key) throws Exception {
                    return get(key);
                }

                public String get(String key) {
                    // 根据key从Redis中获取值
                    String value = (String) redisTemplate.opsForValue().get(key);

                    // 如果value为空时直接读源(mysql)
                    if (value == null || value == "") {
                        Optional<Recruit> optional = recruitDao.findById(Long.parseLong(key));
                        Recruit recruit = optional.get();
                        // 查到内容则将值放入到redis中
                        if(recruit!=null){
                            // 从mysql中返回
                            System.out.println("从mysql中返回");
                            // 在Redis中存在60秒
                            redisTemplate.opsForValue().set(key,recruit.toString(),60,TimeUnit.SECONDS);
                        }
                        return recruit.toString();
                    }
                    // 从Redis中返回
                    System.out.println("从redis中返回");
                    return (String) redisTemplate.opsForValue().get(key);
                }
            });

    @GetMapping("/get")
    public String get(@RequestParam(required = true) String key) throws ExecutionException {
        Object o = null;
        o = cache.getIfPresent(key);
        if(o!= null){
            // 从Guava Cache中返回
            System.out.println("从Guava Cache中返回!");
            return (String)o;
        }
        // 读取缓存
        o = cache.get(key);
        return (String)o;
    }


    /**
     * 查看缓存中的所有数据
     * @return
     */
    @GetMapping("/getall")
    public String getAll(){
        // 将缓存转换为Map并迭代
        Iterator<Map.Entry<String, Object>> iterator = cache.asMap().entrySet().iterator();
        String result = "";
        while (iterator.hasNext()){
            result = result + iterator.next().toString() + "<br/>";
        }
        // 缓存中的元素个数
        long size = cache.size();
        if(size !=0) {
            return "缓存中存在的记录条数:" + String.valueOf(size) + "<br/>"
                    + "结果为:" + "<br/>" + result + "<br/>";
        }else {
            return "当前缓存中无数据";
        }
    }

}
